/*
 * Copyright (C) 2012 Jonathan St-Michel <jonathan@abiwebz.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.abiwebz.platform.components;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JComponent;

/**
 *
 * @author stmicj01
 */
public class Calendar extends JComponent {

    public enum View {
        WEEKLY, MONTHLY, DAILY
    }
    
    public static final int CELL_HEIGHT = 20;
    
    private static final int HOURS = 24;
    private static final int MINUTES = 60;
    private static final int GRADIENT_LENGTH = 30;
    private static final Font HOURS_FONT = new Font("Default", Font.PLAIN, 18);
    
    //private static final
    
    private View view;
    private int interval = 15;
    
    private int mleft, mtop, mright, mbottom;
    
    private Paint plainPaint;
    
    private int gridx, gridy;
    private int colsize;
    
    private int selx, sely;
    
    private boolean paint;
    
    public Calendar() {
        
        setView(View.WEEKLY);
        
        addMouseListener(new MouseListener() {

            @Override
            public void mouseClicked(MouseEvent e) {
                //throw new UnsupportedOperationException("Not supported yet.");
            }

            @Override
            public void mousePressed(MouseEvent e) {
                //throw new UnsupportedOperationException("Not supported yet.");
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                //throw new UnsupportedOperationException("Not supported yet.");
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                //throw new UnsupportedOperationException("Not supported yet.");
            }

            @Override
            public void mouseExited(MouseEvent e) {
                selx = -1;
                sely = -1;
                repaint();
            }
        });
        addMouseMotionListener(new MouseMotionListener() {

            @Override
            public void mouseDragged(MouseEvent e) {
                //throw new UnsupportedOperationException("Not supported yet.");
            }

            @Override
            public void mouseMoved(MouseEvent e) {
                mouseMoved_week(e);
            }
        });
    }
    
    private void mouseMoved_week(MouseEvent e){
        
        if((e.getX() >= gridx) && (e.getY() >= gridy)){
            //System.out.println("mouse moved!");
            int x = 0;
            int y = 0;
            
            x = e.getX() - gridx;
            x = x - (x % colsize);
            x = x / colsize;
            
            y = e.getY() - gridy;
            y = y - (y % CELL_HEIGHT);
            y = y / CELL_HEIGHT;
            
            if(x != selx || y != sely){
                selx = x;
                sely = y;
                repaint();
            }
            
        }
        else{
            //System.out.println("mouse moved! ELSE");
        }
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        if(paint){
            switch(getView()){
                case WEEKLY: {
                    paint_week((Graphics2D)g);
                    break;
                }
                
            }
        }
    }

    private void paint_week(Graphics2D g) {
        int hoursTextHeight = g.getFontMetrics(HOURS_FONT).getHeight() - 5;
        plainPaint = g.getPaint();
        int x = 5;
        int zone1h = 0;
        gridy = zone1h;
        int zone2h = (((HOURS * MINUTES) / interval) * CELL_HEIGHT) + zone1h;
        int time = 0;
        gridx = x + 40;
        colsize = (this.getWidth() - 5 - gridx) / 5;
        
        //Remplir la sélection
        if(selx >= 0 && sely >= 0){
            Color fg = getForeground();
            Color fill = Color.YELLOW;
            g.setColor(fill);
            g.fillRect(gridx + (selx * colsize), gridy + (sely * CELL_HEIGHT), colsize, CELL_HEIGHT);
            g.setColor(fg);
        }
        
        //Les lignes
        for(int y =zone1h; y <= zone2h; y+=CELL_HEIGHT){
            
            if((time % MINUTES) == 0){
                if(time != 0){
                    //g.drawLine(0, y, this.getWidth(), y);
                    drawGradientLine(g, x, y, this.getWidth() -5 - x, true);
                }
                g.setFont(HOURS_FONT);
                g.drawString(formatHours(time / 60), x, y+hoursTextHeight);
                
            }
            else{
                //g.drawLine(15, y, this.getWidth(), y);
                drawGradientLine(g, x+15, y, this.getWidth() - 5 - x, false);
            }
            time += interval;
        }
        
        x = gridx;
        
        int xtemp;
        for(int col = 0; col < 6; col++){
            xtemp = (col * colsize) + x;
            //g.drawLine(xtemp, 0, xtemp, zone2h);
            g.drawRect(xtemp, 0, 1, zone2h);
        }
        
        //g.drawRect(1, 1, this.getWidth() - 2, 2000);
        this.setPreferredSize(new Dimension(this.getWidth() - 2, zone2h + 5));
    }
    
    private String formatHours(int hour){
        return (hour < 10) ? "0" + String.valueOf(hour) : String.valueOf(hour);
    }
    
    private void drawGradientLine(Graphics2D g, int x, int y, int width, boolean bold){
        GradientPaint gp = new GradientPaint(x, y, getBackground(), x+GRADIENT_LENGTH, y+1, getForeground());
        g.setPaint(gp);
        if(bold){
            //g.drawRect(x, y, x+15, 1);
            g.drawRect(x, y, width - x, 1);
            g.setPaint(plainPaint);
            //g.drawRect(x+15, y, width-x-15, 1);
            
        }
        else{
            g.drawLine(x, y, width, y);
            //g.drawLine(x, y, x+15, y);
            g.setPaint(plainPaint);
            //g.drawLine(x+15, y, width, y);
        }
        
    }

    @Override
    public void setSize(Dimension d) {
        super.setSize(d);
        System.out.println("resize!");
    }

    public void setView(View view) {
        this.view = view;
        initialize(view);
    }

    public View getView() {
        return view;
    }
    
    private void initialize(View view){
        paint = false;
        
        selx = -1;
        sely = -1;
        
        switch(view){
            case DAILY:{
                break;
            }
            case MONTHLY:{
                break;
            }
            case WEEKLY:{
                mtop = 5;
                mleft = 5;
                mright = 5;
                mbottom = 5;
                break;
            }
        }
        paint = true;
        repaint();
    }
    
}
